home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d12
/
egxshow.arc
/
SHOWEGA.C
< prev
next >
Wrap
Text File
|
1991-09-17
|
17KB
|
679 lines
/* written in MIX power C version 2.0 */
/* an EGA file viewer */
/* I originally developed this template as a CGA file viewer... */
/* hopefully I have removed anything from that application which */
/* may appear confusing... */
/* writing direct to screen */
/* using bios calls to set the adapter */
#include <stdio.h>
#include <string.h>
#include <dos.h>
#include <bios.h>
#include <conio.h>
#include <direct.h>
#include <malloc.h>
#include <fcntl.h>
#include <io.h>
#include <stdlib.h>
/* a group of handy definitions */
#define BLACK 0
#define BLUE 1
#define GREEN 2
#define CYAN 3
#define RED 4
#define MAGENTA 5
#define BROWN 6
#define WHITE 7
#define GRAY 8
#define LBLUE 9
#define LGREEN 10
#define LCYAN 11
#define LRED 12
#define LMAGENTA 13
#define YELLOW 14
#define BWHITE 15
#define ESCAPE '\x1b'
#define TEXT 3
#define CGA_320 4
#define HERCULES 99
int ADAPTER = CGA_320;
int screen_mode = CGA_320;
#define BLANK 32
#define FAT 219
#define ENTERKEY '\x0d' /* character generated by the Enter Key */
#define ESCKEY '\x1b' /* character generated by the Esc key */
#define FUNCKEY '\x00' /* first character generated by function keys */
#define UPARROW 'H' /* second character generated by up-arrow key */
#define DOWNARROW 'P' /* second character generated by down-arrow key */
#define LTARROW 'K' /* second character generated by left-arrow key */
#define RTARROW 'M' /* second character generated by right-arrow key */
#define PGUP 'I' /* second character generated by page up key */
#define PGDOWN 'Q' /* second character generated by page down key */
/* starting at character 59*/
#define F1 ';' /* second character generated by numerical fkeys */
#define F2 '<'
#define F3 '='
#define F4 '>'
#define F5 '?'
#define F6 '@'
#define F7 'A'
#define F8 'B'
#define F9 'C'
#define F10 'D'
/* ending at character 68 */
#define CRETURN '\x0d'
#define LFEED '\x0A'
#define CTRLZ '\x1a'
#define DELETE '\x7f'
#define SINGLE 218
#define DOUBLE 201
char wildfiles[200][15];
int filecords[84][2]=
{
2, 4, 2, 23, 2, 42, 2, 61,
3, 4, 3, 23, 3, 42, 3, 61,
4, 4, 4, 23, 4, 42, 4, 61,
5, 4, 5, 23, 5, 42, 5, 61,
6, 4, 6, 23, 6, 42, 6, 61,
7, 4, 7, 23, 7, 42, 7, 61,
8, 4, 8, 23, 8, 42, 8, 61,
9, 4, 9, 23, 9, 42, 9, 61,
10, 4, 10, 23, 10, 42, 10, 61,
11, 4, 11, 23, 11, 42, 11, 61,
12, 4, 12, 23, 12, 42, 12, 61,
13, 4, 13, 23, 13, 42, 13, 61,
14, 4, 14, 23, 14, 42, 14, 61,
15, 4, 15, 23, 15, 42, 15, 61,
16, 4, 16, 23, 16, 42, 16, 61,
17, 4, 17, 23, 17, 42, 17, 61,
18, 4, 18, 23, 18, 42, 18, 61,
19, 4, 19, 23, 19, 42, 19, 61,
20, 4, 20, 23, 20, 42, 20, 61,
21, 4, 21, 23, 21, 42, 21, 61,
22, 4, 22, 23, 22, 42, 22, 61};
int getfiles(char *filetype)
{
char buffer[15];
int wildcounter=0;
struct ffblk wild_card;
memset(wildfiles,0,sizeof(wildfiles));
sprintf(buffer,"*.%s",filetype);
if(findfirst(buffer,&wild_card,FA_NORMAL)==0)
{
strcpy(wildfiles[wildcounter],wild_card.ff_name);
wildcounter++;
while(findnext(&wild_card)==0){
strcpy(wildfiles[wildcounter],wild_card.ff_name);
wildcounter++;
}
}
if(wildcounter>1)qsort(wildfiles,wildcounter,15,strcmp);
return wildcounter;
}
#define EGA '\x10'
unsigned char setcrtmode(unsigned char vidmode)
{
union REGS inregs, outregs;
/* set mode */
inregs.h.ah = 0;
inregs.h.al = vidmode;
int86( 0x10, &inregs, &outregs );
/* get mode */
inregs.h.ah = 0xf;
int86( 0x10, &inregs, &outregs );
/* return mode */
return outregs.h.al;
}
/* the structure of an ega color number...
| 5 | 4 | 3 | 2 | 1 | 0 |
| | | | | | |
| R | G | B | R | G | B | color triples (rgb gun values)
|
high | low
intensity intensity
*/
/* byte 0-15 are colors... byte 16 is overscan register */
unsigned char egainfo[17]; /* the values to be used */
void palettebits(int i, unsigned char color,
unsigned char arg1, unsigned char arg2)
{
if(color>0x33)egainfo[i]|=arg1;
if(color>0x77)
{
egainfo[i]&=~arg1;
egainfo[i]|= arg2;
}
if(color>0xbb)egainfo[i]|=(arg1+arg2);
}
void rgb2ega(unsigned char *ptr)
{
int i;
unsigned char color;
for(i=0;i<16;i++)
{
egainfo[i]=0;
color=*ptr++;
palettebits(i,color,0x20,0x04);
color=*ptr++;
palettebits(i,color,0x10,0x02);
color=*ptr++;
palettebits(i,color,0x08,0x01);
}
egainfo[0]=0;
}
int setegapalette()
{
union REGS regs;
unsigned char i;
for(i=0;i<16;i++)
{
regs.h.ah = 0x10; /* function 10h */
regs.h.al = 0x00;
regs.h.bh = egainfo[i];
regs.h.bl = i;
int86(0x10,®s,®s);
}
/* dump data to color registers */
return 0;
}
/* type conversion function */
unsigned int byteword(unsigned char a, unsigned char b){return b<<8|a;}
int checkforpcx(unsigned char *pcxheader)
{
unsigned int zsoft,codetype,pixbits;
unsigned int xmin, ymin, xmax, ymax;
unsigned int no_planes, bytesperline;
int invalid = -1, valid = 0, status=valid;
/* read the file header */
zsoft =pcxheader[0];
codetype=pcxheader[2];
pixbits =pcxheader[3];
if(zsoft!=10) status = invalid;
if(codetype!=1) status = invalid;
if(pixbits !=1) status = invalid;
xmin=byteword(pcxheader[4],pcxheader[5]);
ymin=byteword(pcxheader[6],pcxheader[7]);
xmax=byteword(pcxheader[8],pcxheader[9]);
ymax=byteword(pcxheader[10],pcxheader[11]);
no_planes =pcxheader[65];
bytesperline=byteword(pcxheader[66],pcxheader[67]);
if(xmin != 0 ) status = invalid;
if(ymin != 0 ) status = invalid;
if(xmax != 639) status = invalid;
if(ymax != 349) status = invalid;
if(no_planes!=4) status = invalid;
if(bytesperline !=80)status = invalid;
return status;
}
char indexmap[]={ 1,2,4,8};
void index_set(indexval)
{
outp(0x3c4,2);
outp(0x3c5,indexmap[indexval]);
}
int pcxega(char *name)
{
unsigned long ctr=0;
unsigned long byteoff=0;
unsigned int packet;
unsigned char byte,bytecount;
unsigned char *ptr;
unsigned int temp;
int safety=0;
FILE *fp;
unsigned char pcxheader[128];
if((fp = fopen(name,"rb"))==NULL)return -1;
fread(pcxheader,128,1,fp);
if(checkforpcx(pcxheader)!=0)
{
fclose(fp);
return -1;
}
ptr=(char *)&pcxheader[16];
rgb2ega(ptr);
setegapalette();
temp=0;
index_set(0);
do{ bytecount=1; /* start with a seed count */
byte=fgetc(fp);
/* check to see if its raw */
if(0xC0 == (0xC0 &byte)){ /* if its not, run encoded */
bytecount= 0x3f &byte;
byte=fgetc(fp);
}
switch(temp)
{
case 320: temp=0;
case 0 : ptr=(char *)0xa0000000l+ctr;
index_set(0);
safety=0;
break;
case 80 : ptr=(char *)0xa0000000l+ctr;
index_set(1);
safety=0;
break;
case 160: ptr=(char *)0xa0000000l+ctr;
index_set(2);
safety=0;
break;
case 240: ptr=(char *)0xa0000000l+ctr;
ctr+=80;
safety=0;
index_set(3);
break;
}
for(packet=0;packet<bytecount;packet++){
*ptr++=byte;
byteoff++;
safety++;
temp++;
if(safety>79)packet=bytecount;
}
}while(byteoff<112000l);
fclose(fp);
return 0;
}
void cursoroff(void)
{
union REGS regs;
regs.h.ah = 0x01;
regs.x.cx = 0x2000;
int86(0x10,®s,®s);
}
void cursoron(void)
{
union REGS regs;
regs.h.ah = 0x01;
regs.x.cx = 0x0607;
int86(0x10,®s,®s);
}
void cls(int BACK,int FRONT)
{
union REGS reg;
reg.h.ah = 6;
reg.h.al = 0;
reg.h.ch = 0;
reg.h.cl = 0;
reg.h.dh = 24;
reg.h.dl = 79;
reg.h.bh = (BACK << 4) + FRONT;
int86(0x10, ®, ®);
}
void DMC(int Row, int Column, unsigned BYTE, int BACK, int FRONT, int QUANT)
{
/* DMA replacement for writechs function */
unsigned segment= 0xB000, offset;
int One_Too_Many = (QUANT+1);
int i, Attribute;
Attribute = (BACK << 4) + FRONT;
if(ADAPTER!=HERCULES)segment = 0xB800; /* CGA or Equivalent */
offset = 160 * Row + 2 * Column ;
for (i=1; i< One_Too_Many ; i++){
poke(segment,offset, BYTE|Attribute<<8);
offset+=2;
}
}
void DMM(char *String, int Row, int Column, int BACK, int FRONT)
{
/* DMA replacement for puts
centre justified string */
unsigned Character, segment=0xB000, offset;
int Attribute;
Attribute = (BACK << 4) + FRONT;
Column = ((Column+1)-(.5*(strlen(String))));
if(ADAPTER != HERCULES)segment = 0xB800; /* CGA or Equivalent */
offset = 160 * Row + 2 * Column ;
while ((Character = *String++)!=0){
if(Character!='\n'){
poke(segment,offset,Character|Attribute<<8);
offset+=2;
}
}
}
void DML(char *String, int Row, int Column, int BACK, int FRONT)
{
/* DMA replacement for puts
left justified string */
unsigned Character, segment=0xB000, offset;
int Attribute;
Attribute = (BACK << 4) + FRONT;
if(ADAPTER!=HERCULES)segment = 0xB800; /* CGA or Equivalent */
offset = 160 * Row + 2 * Column ;
while ((Character = *String++)!=0){
if(Character!='\n'){
poke(segment,offset, Character|Attribute<<8);
offset +=2;
}
}
}
void PAINT(int *cor,int fore, int bk,unsigned char Character)
{
int trow=cor[0],tcol=cor[1],brow=cor[2],bcol=cor[3];
int index,linelength = ((bcol+1) - (tcol));
for (index = (trow); index < brow+1; index++)
DMC(index,tcol,Character,bk,fore,linelength);
}
void BORDERBOX(int *cor,int fore, int bk,unsigned char BRDR)
{
int trow=cor[0],tcol=cor[1],brow=cor[2],bcol=cor[3];
/* draws an outline only using a specified border character */
int index;
int homerow = (brow-1);
int homecol = (tcol+1);
int linelength = ((bcol) - (tcol+1));
int TLcorner,TRcorner,BLcorner,BRcorner,HORT,VERT;
switch(BRDR){
case DOUBLE: {
TLcorner = 201;
TRcorner = 187;
BLcorner = 200;
BRcorner = 188;
HORT = 205;
VERT = 186;
break;
}
case SINGLE: {
TLcorner = 218;
TRcorner = 191;
BLcorner = 192;
BRcorner = 217;
HORT = 196;
VERT = 179;
break;
}
default: {
TLcorner = BRDR;
TRcorner = BRDR;
BLcorner = BRDR;
BRcorner = BRDR;
HORT = BRDR;
VERT = BRDR;
}
}
DMC(trow,tcol,TLcorner,bk,fore,1); /* top */
DMC(trow,homecol,HORT,bk,fore,linelength);
DMC(trow,bcol,TRcorner,bk,fore,1);
for (index = (trow+1); index < brow; index++){
DMC(index,tcol,VERT,bk,fore,1);
DMC(index,bcol,VERT,bk,fore,1);
}
DMC(brow,tcol,BLcorner,bk,fore,1);
DMC(brow,homecol,HORT,bk,fore,linelength);
DMC(brow,bcol,BRcorner,bk,fore,1); /* bottom */
}
unsigned char far *crt =(unsigned char *) 0xB8000000l;
void getadaptertype(void)
{
if(((biosequip() >>4) &3) <3)ADAPTER=CGA_320;
else
{
ADAPTER=HERCULES;
crt = (unsigned char far *)0xb0000000l;
}
}
unsigned char far *textscreen;
void initgraphbuffers()
{
textscreen = _fmalloc(4000);
}
void freegraphbuffers()
{
_ffree(textscreen);
}
void bronx(void)
{
sound(60,4);
sound(40,8);
}
/* THE LOADER */
int vux(char *picfile)
{
int status = 0;
char c;
char buffer[66],buffer2[66];
char *wordptr;
strcpy(buffer,picfile);
memcpy(textscreen,crt,4000);
if((setcrtmode(EGA))!=EGA)
{
cls(BLACK,WHITE);
bronx();
puts("EGA adapter required...press any key");
}
else
{
wordptr=strtok(buffer,". \n");
sprintf(buffer2,"%s.PCX",buffer);
status =pcxega(buffer2);
}
if(!status)while((c=getch())!=27);
else bronx();
setcrtmode(TEXT);
cursoroff();
memcpy(crt,textscreen,4000);
return 0;
}
int displayfiles(char *filetype)
{
int i;
int hotfile= 0;
int coldfile=0;
int filecount = getfiles(filetype);
char c;
int background = BLUE, foreground = LCYAN;
int cor[4];
int breverse=BLACK,freverse=BWHITE;
if(ADAPTER==HERCULES){
breverse=WHITE;
freverse=BLACK;
}
if(filecount==0)return 0;
cls(background, foreground);
cursoroff();
cor[0]=0;
cor[1]=0;
cor[2]=24;
cor[3]=79;
BORDERBOX(cor,foreground,background,DOUBLE);
DMC(0,1,1,background,foreground,78);
DMM(
" SHOWEGA(C) Copyright 1991 by Bill Buckels * EGA .PCX file Viewer ",
0,39,background,foreground);
DMM(
" Use Arrow Keys To Select * Press Enter To View | Press ESCape to Exit ",
24,39,background,foreground);
if(filecount>84)filecount=84;
for(i=0;i<filecount;i++)
DML(wildfiles[i],filecords[i][0],filecords[i][1],
background,foreground);
DML(wildfiles[hotfile],filecords[hotfile][0],filecords[hotfile][1],
breverse,freverse);
while((c=getch())!=ESCKEY)
{ if(c==ENTERKEY)vux(wildfiles[hotfile]);
if(c==FUNCKEY)
{
c=getch();
switch(c)
{
case UPARROW : if(hotfile<4)break;
hotfile-=4;
break;
case DOWNARROW: if(hotfile>(filecount-5))break;
hotfile+=4;
break;
case RTARROW :
if(hotfile<(filecount-1))
hotfile++;
break;
case LTARROW : if(hotfile==0)break;
hotfile--;
break;
case PGUP :
case PGDOWN : break;
}
}
if(hotfile!=coldfile)
{
DML(wildfiles[coldfile],
filecords[coldfile][0],filecords[coldfile][1],
background,foreground);
DML(wildfiles[hotfile],
filecords[hotfile][0],filecords[hotfile][1],
breverse,freverse);
coldfile=hotfile;
}
}
cursoron();
cls(BLACK,WHITE);
return 0;
}
main(int argc, char **argv)
{
getadaptertype();
initgraphbuffers();
displayfiles("PCX");
freegraphbuffers();
exit(0);
}